package com.xuecheng.gateway.filters;

import com.alibaba.fastjson.JSON;
import com.xuecheng.commons.utils.AuthInfo;
import com.xuecheng.commons.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/*
* 全局过滤器
* 1.交给容器管理
* 2.实现两个接口
* 3.实现内部的两个方法
* 4.在filter方法中 完成业务逻辑
*
* */
@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {
    /*
    * 核心方法 完成登录检验
    * exchange请求上下文
    * 获取请求的对象和响应的对象
    * chain  过滤器链
    * 方形，向下执行
    *
    * */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //1.排除不需要的验证请求路径 放行
        //1.1获取当前的请求链接
        String path = request.getURI().getPath();
        log.info("请求的path={}", path);
        //1.判断是否需要进行验证
        if (path.contains("coursepub/previes") || path.contains("auth/login") || path.contains("basic/dictionary") || path.contains(
                "category/tree-nodes"
        ) || path.contains("course/upload") || path.contains("search/")) {

            return chain.filter(exchange);
        }
        //2.获取请求头中的token
        String token = request.getHeaders().getFirst("Authorization");
        log.info("请求token", token);
        //3.验证token的时效性
        Boolean ves = JwtUtils.verifyToken(token);//返回true 表示一登录
        //如果token失效  则返回响应401
        if (!ves) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();//返回响应
        }
        //5.如果token有效  方形
        //5.1解析token  获取token中userId ,companyId companyName
        Claims claims = JwtUtils.parserToken(token).getBody();
        Long userId = claims.get("userId", Long.class);
        Long companyId = claims.get("companyId", Long.class);
        String name = claims.get("companyName", String.class);
        //5.2构造java对象 认证对象
        AuthInfo info = new AuthInfo();
        info.setUid(userId);
        info.setCompanyId(companyId);
        info.setCompanyName(name);
        //5.3写入请求头中

        ServerHttpRequest httpRequest = request.mutate().headers(httpHeaders -> {
            httpHeaders.set("payload", JSON.toJSONString(info));
        }).build();
        exchange.mutate().request(httpRequest);
        return chain.filter(exchange);
    }
/*
* 过滤器优先级
*
* */

    @Override
    public int getOrder() {
        return 0;
    }
}
